import { EthereumMonitor } from './EthereumMonitor';
import { BSCMonitor } from './BSCMonitor';
import { BitcoinMonitor } from './BitcoinMonitor';
import { BaseMonitor } from './BaseMonitor';
import { SolanaMonitor } from './SolanaMonitor';
import { createModuleLogger } from '../../utils/logger';
import ChainMonitorConfigService, { ChainMonitorConfig } from '../config/ChainMonitorConfigService';

const logger = createModuleLogger('monitoring-manager');

export interface ChainStatus {
  chain: string;
  isActive: boolean;
  errorCount: number;
  totalTransactions: number;
  lastActivity?: Date;
  status: 'running' | 'stopped' | 'error' | 'starting' | 'stopping';
}

// 全局状态存储，确保跨模块共享
const globalChainStatus = new Map<string, ChainStatus>();
const globalMonitors = new Map<string, any>();

class MonitoringManager {
  private static instance: MonitoringManager;
  private monitors: Map<string, any> = globalMonitors;
  private chainStatus: Map<string, ChainStatus> = globalChainStatus;
  private transactionCallbacks: ((data: any) => void)[] = [];
  private configService: ChainMonitorConfigService;
  private healthCheckInterval: NodeJS.Timeout | null = null;

  private constructor() {
    this.configService = ChainMonitorConfigService.getInstance();
    this.initializeChainStatus();
  }

  public static getInstance(): MonitoringManager {
    if (!MonitoringManager.instance) {
      MonitoringManager.instance = new MonitoringManager();
    }
    return MonitoringManager.instance;
  }

  private initializeChainStatus(): void {
    // 初始化支持的链状态
    const supportedChains = ['ethereum', 'bsc', 'bitcoin', 'base', 'solana'];
    supportedChains.forEach(chain => {
      if (!this.chainStatus.has(chain)) {
        this.chainStatus.set(chain, {
          chain,
          isActive: false,
          errorCount: 0,
          totalTransactions: 0,
          status: 'stopped'
        });
        logger.debug(`📋 初始化 ${chain} 状态: ${this.chainStatus.get(chain)?.status}`);
      }
    });
  }

  public async startAllMonitors(): Promise<void> {
    logger.info('🚀 启动所有已启用的监控器...');
    
    try {
      // 从数据库获取已启用的链配置
      const enabledConfigs = await this.configService.getEnabledChainConfigs();
      
      if (enabledConfigs.length === 0) {
        const allConfigs = await this.configService.getAllChainConfigs();
        if (allConfigs.length === 0) {
          throw new Error('No chain configurations found in database. Please run: node scripts/init-chain-configs.js');
        } else {
          throw new Error(`Found ${allConfigs.length} chain configurations but none are enabled. Please enable chains in the admin interface.`);
        }
      }

      logger.info(`📋 找到 ${enabledConfigs.length} 个已启用的链配置`);

      // 启动所有已启用的监控器
      const startPromises = enabledConfigs.map(async (config: ChainMonitorConfig) => {
        try {
          logger.info(`🔄 启动 ${config.chain} 监控器...`);
          
          // 创建监控器实例
          const monitor = this.createMonitorInstance(config.chain);
          
          // 设置数据库配置到监控器
          if (monitor.setChainConfig) {
            await monitor.setChainConfig(config);
          }

          // 设置交易回调
          this.setupMonitorCallbacks(monitor, config.chain);
          
          // 启动监控器
          await monitor.start();
          
          // 保存监控器实例
          this.monitors.set(config.chain, monitor);
          
          // 更新状态
          this.updateChainStatus(config.chain, {
            isActive: true,
            status: 'running',
            lastActivity: new Date()
          });

          logger.info(`✅ ${config.chain} 监控器启动成功 (配置: min=$${config.minValueUsd})`);
          return { chain: config.chain, success: true };
          
        } catch (error) {
          logger.error(`❌ ${config.chain} 监控器启动失败:`, error);
          this.updateChainStatus(config.chain, {
            isActive: false,
            status: 'error',
            errorCount: (this.chainStatus.get(config.chain)?.errorCount || 0) + 1
          });
          return { 
            chain: config.chain, 
            success: false, 
            error: error instanceof Error ? error.message : String(error)
          };
        }
      });

      const results = await Promise.allSettled(startPromises);
      
      // 分析启动结果
      let successCount = 0;
      let failureCount = 0;
      const failedChains: string[] = [];
      
      results.forEach((result, index) => {
        if (result.status === 'fulfilled') {
          const chainResult = result.value;
          if (chainResult.success) {
            successCount++;
          } else {
            failureCount++;
            failedChains.push(`${chainResult.chain}: ${chainResult.error}`);
          }
        } else {
          failureCount++;
          const config = enabledConfigs[index];
          failedChains.push(`${config.chain}: ${result.reason}`);
        }
      });

      logger.info(`📊 监控器启动完成: 成功 ${successCount} 个, 失败 ${failureCount} 个`);
      
      if (failedChains.length > 0) {
        logger.warn('⚠️ 以下监控器启动失败:');
        failedChains.forEach(failure => logger.warn(`  - ${failure}`));
      }
      
      // 如果没有任何监控器启动成功，抛出错误
      if (successCount === 0) {
        throw new Error(`All ${enabledConfigs.length} enabled monitors failed to start. Check logs and configurations.`);
      }
      
      // 启动健康监控
      this.startHealthMonitoring();
      
    } catch (error) {
      logger.error('❌ 启动监控器失败:', error);
      throw error;
    }
  }

  // 创建监控器实例的工厂方法
  private createMonitorInstance(chain: string): any {
    switch (chain.toLowerCase()) {
      case 'ethereum':
        return new EthereumMonitor();
      case 'bsc':
        return new BSCMonitor();
      case 'bitcoin':
        return new BitcoinMonitor();
      case 'base':
        return new BaseMonitor();
      case 'solana':
        return new SolanaMonitor();
      default:
        throw new Error(`Unsupported chain: ${chain}`);
    }
  }

  public async stopAllMonitors(): Promise<void> {
    logger.info('🔄 停止所有监控器...');
    
    // 清理健康监控
    if (this.healthCheckInterval) {
      clearInterval(this.healthCheckInterval);
      this.healthCheckInterval = null;
      logger.info('✅ 健康监控定时器已清理');
    }
    
    const stopPromises = Array.from(this.monitors.entries()).map(async ([chain, monitor]) => {
      try {
        logger.info(`⏹️ 停止 ${chain} 监控器...`);
        
        // 更新状态为停止中
        this.updateChainStatus(chain, { status: 'stopping' });
        
        // 停止监控器
        if (monitor && monitor.stop) {
          await monitor.stop();
        }
        
        // 更新状态为已停止
        this.updateChainStatus(chain, {
          isActive: false,
          status: 'stopped'
        });
        
        logger.info(`✅ ${chain} 监控器已停止`);
      } catch (error) {
        logger.error(`❌ 停止 ${chain} 监控失败:`, error);
        this.updateChainStatus(chain, {
          isActive: false,
          status: 'error',
          errorCount: (this.chainStatus.get(chain)?.errorCount || 0) + 1
        });
      }
    });

    await Promise.allSettled(stopPromises);
    
    // 清理监控器实例
    this.monitors.clear();
    
    logger.info('✅ 所有监控器已停止');
  }

  private setupMonitorCallbacks(monitor: any, chain: string): void {
    // 设置交易回调
    if (monitor.setTransactionCallback) {
      monitor.setTransactionCallback((transaction: any) => {
        // 更新链状态
        this.updateChainStatus(chain, {
          totalTransactions: (this.chainStatus.get(chain)?.totalTransactions || 0) + 1,
          lastActivity: new Date()
        });

        // 调用所有注册的回调
        this.transactionCallbacks.forEach(callback => {
          try {
            callback(transaction);
          } catch (error) {
            logger.error('交易回调执行失败:', error);
          }
        });
      });
    }
  }

  public addTransactionCallback(callback: (data: any) => void): void {
    this.transactionCallbacks.push(callback);
    logger.debug(`📋 已添加交易回调，当前回调数量: ${this.transactionCallbacks.length}`);
  }

  public updateChainStatus(chain: string, updates: Partial<ChainStatus>): void {
    const currentStatus = this.chainStatus.get(chain);
    if (currentStatus) {
      const newStatus = { ...currentStatus, ...updates };
      this.chainStatus.set(chain, newStatus);
      logger.debug(`📊 更新 ${chain} 状态:`, updates);
    }
  }

  public getAllStatus(): {
    activeCount: number;
    monitorCount: number;
    chains: Record<string, ChainStatus>;
  } {
    const chains: Record<string, ChainStatus> = {};
    let activeCount = 0;

    this.chainStatus.forEach((status, chain) => {
      chains[chain] = { ...status };
      if (status.isActive && status.status === 'running') {
        activeCount++;
      }
    });

    return {
      activeCount,
      monitorCount: this.chainStatus.size,
      chains
    };
  }

  public getChainStatus(chain: string): ChainStatus | undefined {
    return this.chainStatus.get(chain);
  }

  // 新增：启动健康监控
  private startHealthMonitoring(): void {
    // 清理现有的健康监控定时器
    if (this.healthCheckInterval) {
      clearInterval(this.healthCheckInterval);
    }
    
    // 每5分钟进行一次健康检查
    this.healthCheckInterval = setInterval(async () => {
      const activeChains = Array.from(this.monitors.keys());
      
      if (activeChains.length === 0) {
        logger.debug('📊 没有活跃的监控器需要健康检查');
        return;
      }
      
      logger.debug(`📊 开始健康检查 (${activeChains.length} 个监控器)`);
      
      for (const chain of activeChains) {
        try {
          const monitor = this.monitors.get(chain);
          if (!monitor) continue;
          
          // 简单的健康检查：验证监控器是否还在运行
          const status = this.chainStatus.get(chain);
          if (status?.isActive && monitor.isRunning === false) {
            // 监控器状态不一致，标记为错误
            this.updateChainStatus(chain, {
              status: 'error',
              errorCount: (status.errorCount || 0) + 1
            });
            logger.warn(`⚠️ ${chain} 监控器状态不一致，已标记为错误`);
          }
        } catch (error) {
          logger.warn(`⚠️ ${chain} 健康检查失败:`, error);
          const status = this.chainStatus.get(chain);
          this.updateChainStatus(chain, {
            status: 'error',
            errorCount: (status?.errorCount || 0) + 1
          });
        }
      }
    }, 5 * 60 * 1000); // 5分钟
    
    logger.info('✅ 健康监控已启动 (5分钟间隔)');
  }
}

export default MonitoringManager; 